package com.luguangxing.controller;

import com.luguangxing.entity.StatusEntity;
import com.luguangxing.entity.UserEntity;
import com.luguangxing.service.UserService;
import com.luguangxing.utils.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: 小白一号
 * @date: 2022/11/17
 * @desc:
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private RedisTemplate redisTemplate;
    @Autowired
    private UserService userService;
    @Value("${water_card.pricePerSecond}")
    float pricePerSecond;

    /**
     * 查找所有的用户信息（测试用）
     */
    @GetMapping("/findAll")
    public List<UserEntity> findAll() {
        return userService.findAll();
    }

    /**
     * userAccount
     */
    @PostMapping("/findUserByUserAccount")
    public UserEntity findUserByUserAccount(@RequestBody Map<String, Object> map) {
        if (map.get("userAccount").toString() != null) {
            return userService.findByAnyCondition(map);
        }
        return null;
    }

    /**
     * userCardId
     */
    @PostMapping("/findUserByUserCardId")
    public UserEntity findUserByUserCardId(@RequestBody Map<String, Object> map) {
        if (map.get("userCardId").toString() != null) {
            return userService.findByUserCardId(map.get("userCardId").toString());
        }
        return null;
    }

    /**
     * userCardId
     */
    @GetMapping("/getUserBalanceByUserCardId")
    public Map<String, Object> getUserBalanceByUserCardId(@Param("userCardId") String userCardId) {
        Map<String, Object> map = new HashMap();
        UserEntity user = userService.findByUserCardId(userCardId);
        if (user != null) {
            map.put("code", "200");
            map.put("userBalance", user.getUserCardBalance());
            map.put("pricePerSecond", pricePerSecond);
        } else {
            map.put("code", "302");
        }
        return map;
    }

    /**
     * userAccount
     */
    @PostMapping("/getUserBalanceByUserAccount")
    public Object getUserBalanceByUserAccount(@RequestBody Map<String, Object> map) {
        UserEntity user = userService.findByUserAccount(map.get("userAccount").toString());
        if (user != null) {
            map.clear();
            map.put("status", "success");
            map.put("code", "200");
            map.put("userBalance", user.getUserCardBalance());
            map.put("pricePerSecond", pricePerSecond);
        } else {
            map.put("status", "error");
            map.put("code", "302");
        }
        return map;
    }

    /**
     * userAccount,userPassword,userEmail,userPhone
     */
    @PostMapping("/register")
    public Object register(@RequestBody Map<String, Object> map) {
        StatusEntity status = new StatusEntity();
        UserEntity user = new UserEntity();
        String code = "";
        String codeFromRedis = "";
        String phoneOrEmail = "";
        user.setUserAccount(map.get("userAccount").toString());
        user.setUserName(map.get("userName").toString());
        user.setUserPassword(map.get("userPassword").toString());
        try {
            user.setUserEmail(map.get("userEmail").toString());
            user.setUserPhone(map.get("userPhone").toString());
            if (user.getUserEmail().isEmpty() || user.getUserEmail() == null) {
                phoneOrEmail = user.getUserEmail();
            } else if (user.getUserPhone().isEmpty() || user.getUserPhone() == null) {
                phoneOrEmail = user.getUserPhone();
            }
            code = map.get("code").toString();
            // 从Redis中取出验证码
            codeFromRedis = redisTemplate.opsForValue().get(phoneOrEmail).toString();
        } catch (Exception e) {

        } finally {
            if (code.equals(codeFromRedis)) {
                if (userService.insert(user) > 0) {
                    status.setStatus("success");
                    status.setCode("200");
                }
            } else {
                status.setStatus("error");
                status.setCode("302");
            }
        }
        return status;
    }

    /**
     * userAccount,userPassword
     */
    @PostMapping("/login")
    public Object login(@RequestBody Map<String, Object> map) {
        StatusEntity status = new StatusEntity();
        UserEntity user = userService.findByUserAccount(map.get("userAccount").toString());
        if (user == null) {
            status.setStatus("userNoExist");
            status.setCode("302");
        } else {
            if (user.getUserPassword().equals(map.get("userPassword").toString())) {
                status.setStatus("success");
                status.setCode("200");
                user.setUserPassword("**********");
                status.setData(user);
                status.setToken(JWTUtil.generateToken(user.getUserAccount()));
            } else {
                status.setStatus("userPasswordError");
                status.setCode("302");
            }
        }
        return status;
    }

    /**
     * userPhone,code
     */
    @PostMapping("/loginByPhoneCode")
    public Object loginByPhoneCode(@RequestBody Map<String, Object> map) {
        StatusEntity status = new StatusEntity();
        String code = "";
        String codeFromRedis = "";
        String phoneOrEmail = "";
        try {
            phoneOrEmail = map.get("userPhone").toString();
            code = map.get("code").toString();
            codeFromRedis = redisTemplate.opsForValue().get(phoneOrEmail).toString();
        } catch (Exception e) {
        } finally {
            if (code.equals(codeFromRedis)) {
                UserEntity user = userService.findByUserPhone(phoneOrEmail);
                if (user == null) {
                    status.setStatus("userNoExist");
                    status.setCode("302");
                } else {
                    status.setStatus("success");
                    status.setCode("200");
                    user.setUserPassword("**********");
                    status.setData(user);
                    status.setToken(JWTUtil.generateToken(user.getUserAccount()));
                    redisTemplate.delete(phoneOrEmail);
                }
            } else {
                status.setStatus("verifyCodeError");
                status.setCode("302");
            }
        }
        return status;
    }

    /**
     * userEmail,code
     */
    @PostMapping("/loginByEmailCode")
    public Object loginByEmailCode(@RequestBody Map<String, Object> map) {
        StatusEntity status = new StatusEntity();
        String code = "";
        String codeFromRedis = "";
        String phoneOrEmail = "";
        try {
            phoneOrEmail = map.get("userEmail").toString();
            code = map.get("code").toString();
            codeFromRedis = redisTemplate.opsForValue().get(phoneOrEmail).toString();
        } catch (Exception e) {
        } finally {
            if (code.equals(codeFromRedis)) {
                UserEntity user = userService.findByUserEmail(phoneOrEmail);
                if (user == null) {
                    status.setStatus("userNoExist");
                    status.setCode("302");
                } else {
                    status.setStatus("success");
                    status.setCode("200");
                    user.setUserPassword("**********");
                    status.setData(user);
                    status.setToken(JWTUtil.generateToken(user.getUserAccount()));
                    redisTemplate.delete(phoneOrEmail);
                }
            } else {
                status.setStatus("verifyCodeError");
                status.setCode("302");
            }
        }
        return status;
    }

    /**
     * updateWhat、updateValue and condition、conditionValue
     */
    @PostMapping("/updateUserProfile")
    public Object updateUserProfile(@RequestBody Map<String, Object> map, HttpServletRequest request) {
        StatusEntity status = new StatusEntity();
        UserEntity userFromDB = new UserEntity();
        String code = "";
        String codeFromRedis = "";
        String phoneOrEmail = "";
        try {
            String token = request.getHeader("token");
            String condition = map.get("condition").toString();
            code = map.get("code").toString();
            phoneOrEmail = map.get("conditionValue").toString();
            codeFromRedis = redisTemplate.opsForValue().get(phoneOrEmail).toString();
            if (code.equals(codeFromRedis) || !JWTUtil.isTokenExpired(token)) {
                if (condition.equals("userAccount")) {
                    userFromDB = userService.findByUserAccount(map.get("conditionValue").toString());
                } else if (condition.equals("userEmail")) {
                    userFromDB = userService.findByUserEmail(map.get("conditionValue").toString());
                } else if (condition.equals("userPhone")) {
                    userFromDB = userService.findByUserPhone(map.get("conditionValue").toString());
                }
                if (map.get("userPassword") != null) {
                    userFromDB.setUserPassword(map.get("userPassword").toString());
                }
                if (map.get("userName") != null) {
                    userFromDB.setUserName(map.get("userName").toString());
                }
                if (map.get("userAge") != null) {
                    userFromDB.setUserAge(Integer.parseInt(map.get("userAge").toString()));
                }
                if (map.get("userSex") != null) {
                    userFromDB.setUserSex(map.get("userSex").toString());
                }
                if (map.get("userCardId") != null) {
                    userFromDB.setUserCardId(map.get("userCardId").toString());
                }
                if (map.get("userCardBalance") != null) {
                    userFromDB.setUserCardBalance(Float.parseFloat(map.get("userCardBalance").toString()));
                }
                if (map.get("userEmail") != null) {
                    userFromDB.setUserEmail(map.get("userEmail").toString());
                }
                if (map.get("userPhone") != null) {
                    userFromDB.setUserPhone(map.get("userPhone").toString());
                }
            } else {
                status.setStatus("verifyCodeError");
                status.setCode("302");
                return status;
            }
        } catch (
                Exception e) {

        } finally {
            if (userService.updateUserProfile(userFromDB) > 0) {
                status.setStatus("success");
                status.setCode("200");
                redisTemplate.delete(phoneOrEmail);
            } else {
                status.setStatus("error");
                status.setCode("302");
            }
        }
        return status;
    }
}

